#pragma once
#include <iostream>
using namespace std;
#include <unistd.h>
#include <pthread.h>
#include <string>
#include <functional>
#include <assert.h>

class Thread;
class Context
{
public:
    Context():_this(nullptr),_args(nullptr){

    }
    ~Context(){

    }
public:
    Thread *_this;
    void *_args;

};

class Thread
{
    typedef function<void *(void *)> func_t;

public:
    Thread(func_t callback, void *args = nullptr, int number = 0) : _callback(callback), _args(args)
    {
        char buffer[1024];
        snprintf(buffer, sizeof(buffer), "thread-%d", number);
        _name = buffer;
    }

    void start()
    {
        Context* ctx= new Context();
        ctx->_this=this;
        ctx->_args=_args;
        int n = pthread_create(&_tid, nullptr, start_routine, ctx);
        assert(n == 0);
        (void)n;
    }

    static void* start_routine(void* args){//只有一个参数，但是需要传2个参数进来
        Context* ret = static_cast<Context*>(args);

        void* ret2 = ret->_this->_callback(ret->_args);
        delete ret;
        return ret2;
    }

    void join()
    {
        int n = pthread_join(_tid, nullptr);
        //assert(n == 0);
        (void)n;
    }

    ~Thread()
    {
    }

private:
    string _name;
    func_t _callback;
    void *_args;
    pthread_t _tid;
};
